//给你两个下标从 0 开始的数组 nums1 和 nums2 ，和一个二维数组 queries 表示一些操作。总共有 3 种类型的操作： 
//
// 
// 操作类型 1 为 queries[i] = [1, l, r] 。你需要将 nums1 从下标 l 到下标 r 的所有 0 反转成 1 或将 1 反转成 
//0 。l 和 r 下标都从 0 开始。 
// 操作类型 2 为 queries[i] = [2, p, 0] 。对于 0 <= i < n 中的所有下标，令 nums2[i] = nums2[i] +
// nums1[i] * p 。 
// 操作类型 3 为 queries[i] = [3, 0, 0] 。求 nums2 中所有元素的和。 
// 
//
// 请你返回一个数组，包含所有第三种操作类型的答案。 
//
// 
//
// 示例 1： 
//
// 
//输入：nums1 = [1,0,1], nums2 = [0,0,0], queries = [[1,1,1],[2,1,0],[3,0,0]]
//输出：[3]
//解释：第一个操作后 nums1 变为 [1,1,1] 。第二个操作后，nums2 变成 [1,1,1] ，所以第三个操作的答案为 3 。所以返回 [3] 。
//
// 
//
// 示例 2： 
//
// 
//输入：nums1 = [1], nums2 = [5], queries = [[2,0,0],[3,0,0]]
//输出：[5]
//解释：第一个操作后，nums2 保持不变为 [5] ，所以第二个操作的答案是 5 。所以返回 [5] 。
// 
//
// 
//
// 提示： 
//
// 
// 1 <= nums1.length,nums2.length <= 10⁵ 
// nums1.length = nums2.length 
// 1 <= queries.length <= 10⁵ 
// queries[i].length = 3 
// 0 <= l <= r <= nums1.length - 1 
// 0 <= p <= 10⁶ 
// 0 <= nums1[i] <= 1 
// 0 <= nums2[i] <= 10⁹ 
// 
// Related Topics 线段树 数组 👍 25 👎 0


import java.util.HashMap;
import java.util.Map;

//leetcode submit region begin(Prohibit modification and deletion)
class Solution2569 {

    private static final Map<Integer, Integer> REVERT_MAP = new HashMap<Integer, Integer>(){{
        put(1, 0);
        put(0, 1);
    }};

    public long[] handleQuery(int[] nums1, int[] nums2, int[][] queries) {
        // 记录有多少操作3，创建数组
        int len3 = 0;
        for (int[] query : queries) {
            if (query[0] == 3) {
                len3 += 1;
            }
        }
        long[] result = new long[len3];
        int index = 0;

        // 遍历操作
        for (int[] query : queries) {
            int operate = query[0];
            if (operate == 1) {
                // 操作类型 1 为 queries[i] = [1, l, r] 。你需要将 nums1 从下标 l 到下标 r 的所有 0 反转成 1 或将 1 反转成 0 。l 和 r 下标都从 0 开始。
                operate1(nums1, query[1], query[2]);
            }
            if (operate == 2) {
                // 操作类型 2 为 queries[i] = [2, p, 0] 。对于 0 <= i < n 中的所有下标，令 nums2[i] = nums2[i] + nums1[i] * p 。
                operate2(nums1, nums2, query[1]);
            }
            if (operate == 3) {
                // 操作类型 3 为 queries[i] = [3, 0, 0] 。求 nums2 中所有元素的和。
                operate3(nums2, result, index);
                index += 1;
            }
        }

        return result;
    }



    /**
     * 操作类型 1 为 queries[i] = [1, l, r] 。你需要将 nums1 从下标 l 到下标 r 的所有 0 反转成 1 或将 1 反转成 0 。l 和 r 下标都从 0 开始。
     *
     * @param nums1
     * @param l
     * @param r
     */
    private void operate1(int[] nums1, int l, int r) {
        for (int i = l; i <= r; i++) {
            nums1[i] = REVERT_MAP.get(nums1[i]);
        }
    }

    /**
     * 操作类型 2 为 queries[i] = [2, p, 0] 。对于 0 <= i < n 中的所有下标，令 nums2[i] = nums2[i] + nums1[i] * p 。
     *
     * @param nums1
     * @param nums2
     * @param p
     */
    private void operate2(int[] nums1, int[] nums2, int p) {
        for (int i = 0; i < nums2.length; i++) {
            nums2[i] = nums2[i] + nums1[i] * p;
        }
    }

    /**
     * 操作类型 3 为 queries[i] = [3, 0, 0] 。求 nums2 中所有元素的和。
     *
     * @param nums2
     * @param result
     * @param index
     */
    private void operate3(int[] nums2, long[] result, int index) {
        int res = 0;
        for (int num : nums2) {
            res += num;
        }
        result[index] = res;
    }
}
//leetcode submit region end(Prohibit modification and deletion)
